package com.huarui.part.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.ewaf.framework.exception.BizException;
import org.ewaf.framework.model.ListModel;
import org.ewaf.framework.service.BaseService;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;

import com.huarui.dictionary.DictionaryEnum;
import com.huarui.part.dao.ICarModelDao;
import com.huarui.part.dao.IPartCategoryDao;
import com.huarui.part.dao.IPartDao;
import com.huarui.part.dao.IPartOfCarModelDao;
import com.huarui.part.dao.IPartPropertyDao;
import com.huarui.part.dao.IStandardPartDao;
import com.huarui.part.dao.IUnitDao;
import com.huarui.part.error.PartErrorEnum;
import com.huarui.part.model.CarModel;
import com.huarui.part.model.MeasurementUnit;
import com.huarui.part.model.Part;
import com.huarui.part.model.PartCategory;
import com.huarui.part.model.PartListModel;
import com.huarui.part.model.PartOfCarModel;
import com.huarui.part.model.PartProperty;
import com.huarui.part.model.StandardPart;
import com.huarui.part.util.PartOperateResultEnum;
import com.huarui.payInvoice.util.PayInvoiceMessageEnum;
import com.huarui.quotation.service.QuotationService;
import com.huarui.user.model.SessionMessage;
import com.huarui.user.security.UserHolder;
import com.huarui.util.JsonUtil;
import com.huarui.util.PinyinToolkit;

public class PartService extends BaseService {
	private final static Logger logger = Logger.getLogger(PartService.class);
	
	private IUnitDao unitDao;

	private ICarModelDao carModelDao;

	private IPartCategoryDao partCategoryDao;

	private IStandardPartDao standardPartDao;

	private IPartPropertyDao partPropertyDao;

	private IPartOfCarModelDao partOfCarModelDao;
	
	private QuotationService quotationService;

	/**
	 * 增加计量单位记录
	 * 
	 * @param unit
	 * @throws BizException
	 */
	public void createMeasurementUnit(MeasurementUnit unit) throws BizException {

		// 先判断单位是否重复

		if (unitDao.getByName(unit.getName()) != null) {
			throw new BizException(PartErrorEnum.DOUBLE_NAME, unit.getName());
		} else {
			unitDao.create(unit);
		}

	}

	/**
	 * 
	 * @return
	 */
	public List<MeasurementUnit> getAllUnits() {

		return unitDao.getAllUnits();

	}

	public List<MeasurementUnit> getAllUnitsExt() {

		return unitDao.getAllUnitsExt();

	}

	/**
	 * 查询计量单位
	 * 
	 * @param id
	 * @return
	 */
	public MeasurementUnit getUnitById(Integer id) {

		return (MeasurementUnit) unitDao.getById(id);
	}

	/**
	 * 更新计量单位
	 * 
	 * @param units
	 */
	public boolean updateUnits(MeasurementUnit unit) {
		if (unitDao.getByName(unit.getName()) != null) {
			throw new BizException(PartErrorEnum.DOUBLE_NAME, unit.getName());
		} else {
			return unitDao.update(unit);
		}

	}

	/**
	 * 增加车型记录
	 * 
	 * @param carModel
	 * @throws BizException
	 */
	public void createCarModel(CarModel carModel) throws BizException {

		carModelDao.create(carModel);
	}

	/**
	 * 查询所有车型记录
	 * 
	 * @return
	 */
	public List<CarModel> getCarModels(String key) {

		return carModelDao.searchCarModels(key);
	}

	/**
	 * 查询车型
	 * 
	 * @param id
	 * @return
	 */
	public CarModel getCarModelById(Integer id) {

		return (CarModel) carModelDao.getById(id);
	}

	/**
	 * 更新车型
	 * 
	 * @param carModel
	 * @return
	 */
	public boolean updateCarModel(CarModel carModel) {
		return carModelDao.update(carModel);

	}

	/**
	 * 增加零件类别记录
	 * 
	 * @param partCagegory
	 * @throws BizException
	 */
	public void createPartCategory(PartCategory partCagegory)
			throws BizException {

		partCategoryDao.create(partCagegory);
	}

	public List<PartCategory> getCategoryLevelList() {
		return partCategoryDao.getFirstLevel();

	}

	public PartCategory getCategoryById(Integer id) {

		return (PartCategory) partCategoryDao.getById(id);
	}

	/**
	 * 根据一级类别id查询子类别
	 * 
	 * @param level1Id
	 * @return
	 */
	public List<PartCategory> getSubLevel(Integer level1Id) {

		return partCategoryDao.getSubLevel(level1Id);
	}

	/**
	 * 根据id查询子类别
	 * @param id
	 * @return
	 */
	public List<PartCategory> getSubLevelById(Integer id) {

		return partCategoryDao.getSubLevelById(id);
	}
	
	
	
	/**
	 * 更新零件类别
	 * 
	 * @param category
	 * @return
	 */
	public boolean updateCategory(PartCategory category) {

		return partCategoryDao.update(category);

	}

	/**
	 * 增加零件
	 * 
	 * @param part
	 * @throws BizException
	 */
	public void createPart(Part part) throws BizException {

		this.getDao().create(part);

	}
	
	/**
	 * 更新零件信息
	 * 
	 * @param part
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> updatePart(final Part part) {
		Map<String, Object> resultMap = (Map<String, Object>) transactionTemplate
				.execute(new TransactionCallback() {

					Map<String, Object> resultMap = new HashMap<String, Object>();

					@Override
					public Object doInTransaction(TransactionStatus status) {
						try {

							Part p = (Part) getDao().getById(part.getId());
							if (p != null) {
								p.setName(part.getName());
								p.setNameEn(part.getNameEn());
								p.setLevel1Id(part.getLevel1Id());
								p.setLevel1Name(part.getLevel1Name());
								p.setLevel2Name(part.getLevel2Name());
								p.setMeasurementUnit(part.getMeasurementUnit());
								p.setPartCategoryId(part.getPartCategoryId());
								p.setPyCode(PinyinToolkit.cn2FirstSpell(part
										.getName()));
								getDao().update(p);
							}
							resultMap.put(
									PartOperateResultEnum.SUCCESS.getMsg(),
									true);
							resultMap.put("msg",
									PartOperateResultEnum.OK_MSG_SUCCESS
											.getMsg());

						} catch (Exception e) {
							logger.error("partUpload更新保存错误", e);
							status.setRollbackOnly();
							resultMap.put(PartOperateResultEnum.SUCCESS
									.getMsg(),
									false);
							resultMap.put("msg", PartOperateResultEnum.ERROR_MSG_DATABASE
											.getMsg());
						}

						return resultMap;
					}
				});
		return resultMap;
	}

	/**
	 * 根据编码和来源,公司id查询唯一Part
	 * 
	 * @param code
	 * @param source
	 * @param companyId
	 * @return
	 */
	public Part getPartByCodeAndSource(String code, int source,
			Integer companyId) {

		return getDao().getPartByCodeAndSource(code, source, companyId);
	}

	public Part getPartById(Integer id) {

		return (Part) getDao().getById(id);
	}

	public List<Part> getPartList() {

		return this.getDao().getPartListModel();
	}

	/**
	 * 根据条件查询零件
	 * 
	 * @param map
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Map> getPartListByConditions(ListModel lm, Map map) {
		map.put("varGroup", DictionaryEnum.GROUP_SOURCE.getGroup());
		Integer count = getDao().getPartListCountByConditions(map);
		lm.setTotal(count);
		map.put("listModel", lm);
		return getDao().getPartsForMapByConditions(map);
	}

	/**
	 * 增加标准零件
	 * 
	 * @param stdPart
	 * @throws BizException
	 */
	public void createStdPart(StandardPart stdPart) throws BizException {

		standardPartDao.create(stdPart);
	}

	public List<StandardPart> getStandardPartList() {

		return standardPartDao.getAllStandardParts();
	}

	public StandardPart getStandardPartById(Integer id) {

		return (StandardPart) standardPartDao.getById(id);
	}

	/**
	 * 增加配件属性(每个配件在每一公司只能有一条记录)
	 * 
	 * @param partProperty
	 */
	public void createPartProperty(PartProperty partProperty) {

		partPropertyDao.create(partProperty);
	}

	public PartProperty getPartPropertyById(Integer partPropertyId) {

		return (PartProperty)partPropertyDao.getById(partPropertyId);
	}

	public ListModel<PartProperty> getPartPropertyListModel() {

		ListModel<PartProperty> listModel = new ListModel<PartProperty>();

		List<PartProperty> list = partPropertyDao.getPartCategoryListModel();
		listModel.setResult(list);

		return listModel;
	}

	/**
	 * 更新配件属性
	 * 
	 * @param partProperty
	 * @return
	 */
	public boolean updatePartProperty(PartProperty partProperty) {

		return partPropertyDao.update(partProperty);
	}

	/**
	 * 根据partId 和公司id 获得配件属性记录
	 * 
	 * @param partId
	 * @param companyId
	 * @return
	 */
	public PartProperty getPartPropertyByPartIdAndCompanyId(int partId,
			int companyId) {

		return partPropertyDao.getPartPropertyByPartIdAndCompanyId(partId,
				companyId);
	}

	public void createPartOfCarModel(PartOfCarModel partOfCarModel) {

		partOfCarModelDao.create(partOfCarModel);
	}

	public ListModel<PartOfCarModel> getPartOfCarModePage() {

		ListModel<PartOfCarModel> listModel = new ListModel<PartOfCarModel>();

		List<PartOfCarModel> list = partOfCarModelDao.getAll();
		listModel.setResult(list);
		return listModel;

	}

	public boolean updatePartOfCarModel(PartOfCarModel partOfCarModel) {

		return partOfCarModelDao.update(partOfCarModel);
	}

	@SuppressWarnings("unchecked")
	public Part getPartByConditions(Map map) {
		return this.getDao().getPartByConditions(map);
	}

	@SuppressWarnings("unchecked")
	public Map getPartByConditionsJson(Map map) {
		return getDao().getPartByConditionsJson(map);
	}

	@SuppressWarnings("unchecked")
	public PartProperty getPartPropertyByConditions(Map map) {
		List<PartProperty> list = getPartPropertyListByConditions(map);
		return list.size() > 0 ? list.get(0) : null;
	}

	@SuppressWarnings("unchecked")
	public List<PartProperty> getPartPropertyListByConditions(Map map) {
		return partPropertyDao.getPartPropertyListByConditions(map);
	}
	public List<Map> getPartPropertyListMapByConditions(Map<String,Object> map){
		return partPropertyDao.getListMapByCondition(map);
	}
	public Map getPartPropertyMapByConditions(Map<String,Object> map){
		List<Map> list = getPartPropertyListMapByConditions(map);
		return list.size() == 1 ? list.get(0) : null;
	}
	@SuppressWarnings("unchecked")
	public ListModel getPartPropertyByCompanyId(PartListModel lm) {

		lm.setTotal(partPropertyDao.countByConditions(lm));

		List<PartProperty> partPropertyList = partPropertyDao.queryPartProperty(lm);

		lm.setResult(partPropertyList);

		return lm;
	}

	public void deletePartProperty(Integer companyId, Integer id) {

		partPropertyDao.deletePartProperty(companyId, id);
	}

	@SuppressWarnings("unchecked")
	public ListModel<Part> getAllParts(ListModel<Part> lm) {

		lm.setTotal(this.getDao().countByCondition(lm));
		Map map = new HashMap<String, String>();
		map.put("orderBy", lm.getOrderBy());
		map.put("start", lm.getStart());
		map.put("pageSize", lm.getPageSize());
		map.put("desc", lm.isDesc());
		List<Part> partList = this.getDao().getAllParts(map);
		lm.setResult(partList);

		return lm;

	}

	@SuppressWarnings("unchecked")
	public ListModel<Part> getAllComboxPart(ListModel lm, String queryParam) {

	
		Map map = new HashMap<String, String>();

		String regNubmer = "^[0-9A-Za-z]+$";
		String regABC = "^[A-Za-z]+$";

		if (StringUtils.isNotBlank(queryParam)) {

			if (queryParam.matches(regABC)) {

				map.put("pyCode", queryParam);

			} else if (queryParam.matches(regNubmer)) {

				map.put("code", queryParam);
			} else {

				map.put("name", queryParam);
			}

		}

		map.put("start", lm.getStart());
		map.put("pageSize", lm.getPageSize());
		
	    lm.setTotal(this.getDao().getcountByCondition(map));
		

		List<Part> partnerList = this.getDao().getAllComboxPart(map);

		lm.setResult(partnerList);

		return lm;
	}

	private IPartDao getDao() {

		return (IPartDao) dao;
	}

	public void setUnitDao(IUnitDao unitDao) {
		this.unitDao = unitDao;
	}

	public void setCarModelDao(ICarModelDao carModelDao) {
		this.carModelDao = carModelDao;
	}

	public void setPartCategoryDao(IPartCategoryDao partCategoryDao) {
		this.partCategoryDao = partCategoryDao;
	}

	public void setStandardPartDao(IStandardPartDao standardPartDao) {
		this.standardPartDao = standardPartDao;
	}

	public void setPartPropertyDao(IPartPropertyDao partPropertyDao) {
		this.partPropertyDao = partPropertyDao;
	}

	public void setPartOfCarModelDao(IPartOfCarModelDao partOfCarModelDao) {
		this.partOfCarModelDao = partOfCarModelDao;
	}

	public PartProperty getPartPropertyByPartId(Integer partId,
			Integer companyId) {
		return partPropertyDao.getPartPropertyByPartId(partId, companyId);
	}

	/**
	 * 后台查询
	 * @param paramsMap
	 * @return
	 */
	public Map<String, Object> getPartCategoryListByComplex(Map<String, Object> paramsMap) {
		Integer totalProperty = partCategoryDao.getPartCategoryListCountByComplex(paramsMap);
		List<Map<String, Object>> list = partCategoryDao.getPartCategoryListByComplex(paramsMap);
		paramsMap.clear();
		paramsMap.put("totalProperty", totalProperty);
		paramsMap.put("root", list);
		return paramsMap;
	}
	
	/**
	 * 后台查询
	 * @param paramsMap
	 * @return
	 */
	public Map<String, Object> getMeasurementUnitListByComplex(Map<String, Object> paramsMap) {
		Integer totalProperty = this.unitDao.getMeasurementUnitListCountByComplex(paramsMap);
		List<Map<String, Object>> list = this.unitDao.getMeasurementUnitListByComplex(paramsMap);
		paramsMap.clear();
		paramsMap.put("totalProperty", totalProperty);
		paramsMap.put("root", list);
		return paramsMap;
	}
	
	/**
	 * 后台查询
	 * @param paramsMap
	 * @return
	 */
	public Map<String, Object> getStandardPartListByComplex(Map<String, Object> paramsMap) {
		Integer totalProperty = this.standardPartDao.getStandardPartListCountByComplex(paramsMap);
		List<Map<String, Object>> list = this.standardPartDao.getStandardPartListByComplex(paramsMap);
		paramsMap.clear();
		paramsMap.put("totalProperty", totalProperty);
		paramsMap.put("root", list);
		return paramsMap;
	}
	
	/**
	 * 后台查询
	 * @param paramsMap
	 * @return
	 */
	public Map<String, Object> getCarModelListByComplex(Map<String, Object> paramsMap) {
		Integer totalProperty = this.carModelDao.getCarModelListCountByComplex(paramsMap);
		List<Map<String, Object>> list = this.carModelDao.getCarModelListByComplex(paramsMap);
		paramsMap.clear();
		paramsMap.put("totalProperty", totalProperty);
		paramsMap.put("root", list);
		return paramsMap;
	}
	
	/**
	 * 后台查询
	 * @param paramsMap
	 * @return
	 */
	public Map<String, Object> getPartOfCarModelListByComplex(Map<String, Object> paramsMap) {
		Integer totalProperty = this.partOfCarModelDao.getPartOfCarModelListCountByComplex(paramsMap);
		List<Map<String, Object>> list = this.partOfCarModelDao.getPartOfCarModelListByComplex(paramsMap);
		paramsMap.clear();
		paramsMap.put("totalProperty", totalProperty);
		paramsMap.put("root", list);
		return paramsMap;
	}

	@SuppressWarnings("unchecked")
	public ListModel getPartCodeListByConditions(ListModel lm,Map<String, Object> map) {	
		lm.setTotal(getDao().getPartCodeCountByConditions(map));
		map.put("listModel", lm);
		lm.setResult(getDao().getPartCodeListByConditions(map));
		return lm;
	}

	/**
	 * 查询partProperty
	 * @param queryParam
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public JSONObject getPartPropertyByConditions(String queryParam) {
		SessionMessage sm = UserHolder.getCurrentSessionMessage();
		JSONObject queryObject = JSONObject.fromObject(queryParam);
		Map queryMap = (Map) JSONObject.toBean(queryObject,Map.class);
		queryMap.put("companyId", sm.getCompanyId());
		PartProperty partProperty = partPropertyDao.getPartPropertyByConditions(queryMap);
		JSONObject response = new JSONObject();
		if(partProperty == null){
			queryMap.remove("companyId");
			Part part = getDao().getPartByConditions(queryMap);
			response.put("code", part.getCode());
			response.put("source", part.getSource());
			response.put("name", part.getName());
			response.put("measurementUnit", part.getMeasurementUnit());
			response.put("msg", "请先建立该零件属性信息!");			
			response.put("hasPro", false);			
		}else{
			response = JSONObject.fromObject(partProperty);
			response.put("hasPro", true);
		}
		return response;
	}
	
	public Map<String,Object> pagingByCondition(Map<String,Object> map,ListModel lm){
		Map<String,Object> resultMap = new HashMap<String, Object>();
		try {
			Integer count=partPropertyDao.getCountByCondition(map);
			map.put("listModel", lm);
			List<Map> resList = partPropertyDao.getListMapByCondition(map);
			resultMap.put("root", resList);
			resultMap.put("totalProperty",count);
		
		} catch (Exception e) {
			logger.error("零件表查询出错", e);
		}
		return resultMap;
	}
	public Map<String,Object> savePartProperties(final List<PartProperty> list){
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			SessionMessage sm=UserHolder.getCurrentSessionMessage();
			List<PartProperty> updateList=new ArrayList<PartProperty>();
			for(PartProperty partProperty:list){
				PartProperty obj=partPropertyDao.getPartPropertyByPartId(partProperty.getPartId(), sm.getCompanyId(),true);
				if(obj==null)continue;
				obj.setRetailPrice(partProperty.getRetailPrice());
				obj.setInsurancePrice(partProperty.getInsurancePrice());
				obj.setPublicanLevel(partProperty.getPublicanLevel());
				obj.setQuotationQty(partProperty.getQuotationQty());
				updateList.add(obj);
			}
			quotationService.batchOperationQuotation(updateList);
			resultMap.put(PayInvoiceMessageEnum.SUCCESS.getMsg(), PayInvoiceMessageEnum.RESULT_TYPE_SUCCESS.getMsg());
		} catch (Exception e) {
			logger.error("零件表保存出错", e);
			resultMap.put(PayInvoiceMessageEnum.SUCCESS.getMsg(),PayInvoiceMessageEnum.ERROR_MSG_DATABASE.getMsg());
			return resultMap;
		}
		resultMapInfo(resultMap);
		return resultMap;
	}
	private void resultMapInfo(Map<String,Object> resultMap){
		if(!resultMap.containsKey(PayInvoiceMessageEnum.SUCCESS.getMsg())){
			resultMap.put(PayInvoiceMessageEnum.SUCCESS.getMsg(),PayInvoiceMessageEnum.RESULT_TYPE_SUCCESS.getMsg());
		}
	}
	public Map<String,Object> savePartProperty(final PartProperty partProperty){
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			SessionMessage sm=UserHolder.getCurrentSessionMessage();
			Map<String, Object> map = new HashMap<String, Object>();
			List<PartProperty> list=new ArrayList<PartProperty>();
			map.put("companyId",sm.getCompanyId());
			map.put("source", partProperty.getSource());
			map.put("code", partProperty.getCode());
			map.put("isLock", true);
			PartProperty datebsePartProperty=getPartPropertyByConditions(map);
			if(datebsePartProperty!=null){//修改
				if(partProperty.getId()!=null){
					editpartProperty(datebsePartProperty,partProperty);
					list.add(datebsePartProperty);
				}else{
					throw new RuntimeException();
				}
			}else{//新增
				setPropertiesFromPart(partProperty);
				list.add(partProperty);
			}
			quotationService.batchOperationQuotation(list);
			resultMap.put(PayInvoiceMessageEnum.SUCCESS.getMsg(), PayInvoiceMessageEnum.RESULT_TYPE_SUCCESS.getMsg());
			resultMap.put("partProperty", partProperty);
		} catch (Exception e) {
			logger.error("零件表保存出错", e);
			resultMap.put(PayInvoiceMessageEnum.SUCCESS.getMsg(),PayInvoiceMessageEnum.ERROR_MSG_DATABASE.getMsg());
			return resultMap;
		}
		resultMapInfo(resultMap);
		return resultMap;
	}
	private void editpartProperty(PartProperty d,PartProperty p){
		d.setSwapCode(p.getSwapCode());
		d.setPublicanLevel(p.getPublicanLevel());
		d.setCarModel(p.getCarModel());
		d.setBrand(p.getBrand());
		d.setOrigin(p.getOrigin());
		d.setMinOnHand(p.getMinOnHand());
		d.setMaxOnHand(p.getMaxOnHand());
		d.setMinPrice(p.getMinPrice());
		d.setRetailPrice(p.getRetailPrice());
		d.setInsurancePrice(p.getInsurancePrice());
		d.setQuotationQty(p.getQuotationQty());
		
	}
	private void setPropertiesFromPart(PartProperty partProperty) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("source", partProperty.getSource());
		map.put("code", partProperty.getCode());
		Part part=this.getDao().getPartByConditions(map);
		partProperty.setCost(BigDecimal.ZERO);
		partProperty.setPartId(part.getId());
		partProperty.setOnHand(0);
		partProperty.setOnWay(0);
		partProperty.setNameEn(part.getNameEn());
		partProperty.setName(part.getName());
		partProperty.setLevel1Id(part.getLevel1Id());
		partProperty.setLevel1Name(part.getLevel1Name());
		partProperty.setLevel2Name(part.getLevel2Name());
		partProperty.setPartCategoryId(part.getPartCategoryId());
		partProperty.setDurability(part.getDurability());
		partProperty.setPyCode(part.getPyCode());
		partProperty.setMeasurementUnit(part.getMeasurementUnit());
	}
	public void setQuotationService(QuotationService quotationService) {
		this.quotationService = quotationService;
	}
	
	public Map<String,Object> findPartByCodeAndSource(Part part){
		SessionMessage sm=UserHolder.getCurrentSessionMessage();
		Map<String,Object> resultMap=new HashMap<String, Object>();
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("source", part.getSource());
		map.put("code", part.getCode());
		map.put("companyId", sm.getCompanyId());
		PartProperty partProperty=partPropertyDao.getByCondition(map);
		if(partProperty!=null){
			resultMap.put(JsonUtil.RESULT_TYPE_SUCCESS,JsonUtil.RESULT_FAILURE);
			resultMap.put(JsonUtil.RESULT_MSG, "已经存在该零件!");
		}else{
			map.remove("comapnyId");
			Part dbPart=getDao().getPartByConditions(map);
			resultMap.put(JsonUtil.RESULT_TYPE_SUCCESS,JsonUtil.RESULT_SUCCESS);
			resultMap.put("part", dbPart);
		}
		return resultMap;
	}
	
}
